import tkinter as tk
from tkinter import messagebox, filedialog
from collections import deque
import json
import tkinter.ttk as ttk
import random

class Task:
    def __init__(self, title, description, priority,timeslice):
        self.title = title #名称
        self.description = description #描述
        self.priority = priority #优先级
        self.timeslice = timeslice #时间片
        self.remaining_time = 0 #剩余运行时间
        self.taskcode = 0 #任务识别码
    def to_dict(self):
        return {"title": self.title, "description": self.description, "priority": self.priority}

    @staticmethod
    def from_dict(data):
        return Task(data["title"], data["description"], data["priority"])

    def __str__(self):
        return f"[{self.title}] {self.description[:10]}... | 优先级: {self.priority}| 时间片: {self.timeslice}s| 任务码: {self.taskcode:04d}"


class SchedulerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("任务调度器")

        # 调度器内部状态
      
        self.task_queue = deque()  # 就绪队列
        self.running_task = None
        self.update_interval = 1000
        self.timer = None
        self.is_running = False
        self.completed_tasks = []  # 存储已完成的任务

        self.create_completed_listbox() 
        # GUI 元素
        self.create_widgets()

        # 启动调度器
        self.start_scheduler()
    def create_completed_listbox(self):
        tk.Label(self.root, text="已完成任务:").grid(row=0, column=3, columnspan=2)

        self.completed_listbox = tk.Listbox(self.root, width=50, height=15)
        self.completed_listbox.grid(row=1, column=3, rowspan=10, padx=10)

        # 绑定点击事件
        self.completed_listbox.bind("<<ListboxSelect>>", self.readd_task_from_completed)

    def add_to_completed(self, task):
        self.completed_tasks.append(task)
        self.update_completed_listbox()
    

    def update_completed_listbox(self):
        self.completed_listbox.delete(0, tk.END)
        for task in self.completed_tasks:
            self.completed_listbox.insert(tk.END, str(task))
    def readd_task_from_completed(self, event):
        selected = self.completed_listbox.curselection()
        if not selected:
            return

        index = selected[0]
        task = self.completed_tasks[index]

        # 重置任务状态
        task.remaining_time = task.timeslice  # 重置剩余时间
        self.task_queue.append(task)
        self.task_queue = deque(sorted(self.task_queue, key=lambda t: t.priority))

        # 从已完成列表中移除
        self.completed_tasks.pop(index)

        self.update_completed_listbox()
        self.update_task_listbox()
    
    def create_widgets(self):
        # 新建任务区域
        tk.Label(self.root, text="任务标题:").grid(row=0, column=0)
        self.title_entry = tk.Entry(self.root, width=30)
        self.title_entry.grid(row=0, column=1)

        tk.Label(self.root, text="任务简介:").grid(row=1, column=0)
        self.desc_entry = tk.Entry(self.root, width=30)
        self.desc_entry.insert(0, "-")
        self.desc_entry.grid(row=1, column=1)

        tk.Label(self.root, text="优先级 (0为最高):").grid(row=2, column=0)
        self.priority_entry = tk.Entry(self.root, width=30)
        self.priority_entry.grid(row=2, column=1)

        # 设置时间片
        tk.Label(self.root, text="时间片大小 (秒):").grid(row=3, column=0)
        self.slice_entry = tk.Entry(self.root, width=30)
        self.slice_entry.insert(0, str(600))
        self.slice_entry.grid(row=3, column=1)

        self.add_button = tk.Button(self.root, text="添加任务", command=self.add_task)
        self.add_button.grid(row=3, column=2, columnspan=2)


        tk.Label(self.root, text="任务码:").grid(row=5, column=0)
        self.complete_taskcode = tk.Entry(self.root, width=30)
        self.complete_taskcode.grid(row=5, column=1)

        self.complete_button = tk.Button(self.root, text="标记为完成", command=self.mark_complete)
        self.complete_button.grid(row=5, column=2)
        # 控制按钮
        self.pause_button = tk.Button(self.root, text="暂停", command=self.pause_scheduler)
        self.pause_button.grid(row=6, column=0)

        self.resume_button = tk.Button(self.root, text="继续", command=self.resume_scheduler)
        self.resume_button.grid(row=6, column=1)



        # 任务列表显示
        self.task_listbox = tk.Listbox(self.root, width=70, height=10)
        self.task_listbox.grid(row=10, column=0, columnspan=2)

    
        # 可选：进度条
        self.progress_bar = ttk.Progressbar(self.root, orient="horizontal", length=300, mode="determinate")
        self.progress_bar.grid(row=11, column=0, columnspan=2, pady=5)
        

    def add_task(self):
        

        title = self.title_entry.get() #任务标题
        desc = self.desc_entry.get() #任务描述
        priority_str = self.priority_entry.get() #优先级
        time_slice = self.slice_entry.get() #时间片大小

        if not title or not desc or not priority_str.isdigit()or not time_slice.isdigit():
            messagebox.showwarning("输入错误", "请填写完整信息，优先级为数字,时间片大小为数字")
            return

        priority = int(priority_str)
        timeslice = int(time_slice)
        task = Task(title, desc, priority,timeslice)
        task.remaining_time = timeslice #设置剩余运行时间

      
        existing_codes = {taski.taskcode for taski in self.task_queue if taski.taskcode != 0}
       
        while True:
            new_code = random.randint(0, 9999)
            if new_code not in existing_codes:
                task.taskcode = new_code
                break

        self.task_queue.append(task)
        self.task_queue = deque(sorted(self.task_queue, key=lambda t: t.priority))


        self.update_task_listbox()



    def start_scheduler(self):
        self.is_running = True
        self.schedule_next()

    def schedule_next(self):
        if not self.is_running:
            return

        if self.running_task:
            if self.running_task.remaining_time > 0:
                self.running_task.remaining_time -= 1
                self.root.after(self.update_interval, self.schedule_next)
                self.update_task_listbox()
                return

        # 当前任务结束或无任务
        if self.task_queue:
            overtask = self.running_task
            self.running_task = self.task_queue.popleft()
            self.running_task.remaining_time = self.running_task.timeslice
            self.task_queue.append(overtask) # 重新加入队列
            print(self.task_queue)
            self.task_queue = deque(sorted((t for t in self.task_queue if t is not None),key=lambda t: t.priority))
        else:
            self.running_task = None

        self.update_task_listbox()
        self.root.after(self.update_interval, self.schedule_next)

    def pause_scheduler(self):
        self.is_running = False

    def resume_scheduler(self):
        self.is_running = True
        self.schedule_next()

    def mark_complete(self):

        taskcoden = self.complete_taskcode.get()
        print(taskcoden)
        print(f"self.running_task.taskcode = {self.running_task.taskcode} {taskcoden == self.running_task.taskcode}")
        if int(taskcoden) == self.running_task.taskcode:
            completed_task = self.running_task
            self.add_to_completed(completed_task)
            self.running_task = None
            # self.schedule_next()
            return
        else:
            new_queue = deque()
            for task in self.task_queue:
                if task.taskcode == int(taskcoden):
                    pass
                else:
                    new_queue.append(task)
            self.task_queue = new_queue  # 替换旧队列
            self.task_queue = deque(sorted((t for t in self.task_queue if t is not None),key=lambda t: t.priority))
        return

    def update_task_listbox(self):
        self.task_listbox.delete(0, tk.END)  # 清空任务列表

        # 显示当前运行的任务
        if self.running_task:
            if hasattr(self.running_task, 'remaining_time'):
                remaining = self.running_task.remaining_time
                self.task_listbox.insert(tk.END, f"▶ 正在运行: {self.running_task} | 剩余时间: {remaining} 秒")
                # 更新进度条
                self.progress_bar["maximum"] = self.running_task.timeslice 
                if self.running_task.timeslice > 0:
                    self.progress_bar["value"] = remaining
                else:
                    self.progress_bar["value"] = 0
            else:
                self.task_listbox.insert(tk.END, f"▶ 正在运行: {self.running_task} | 剩余时间: --")
        else:
            self.task_listbox.insert(tk.END, "▶ 正在运行: 无任务")

        self.task_listbox.insert(tk.END, "------------------------")
        self.task_listbox.insert(tk.END, "等待中的任务:")

        # 显示等待中的任务
        for task in self.task_queue:
            self.task_listbox.insert(tk.END, str(task))

if __name__ == "__main__":
    root = tk.Tk()
    app = SchedulerApp(root)
    root.mainloop()